package com.ocom.accesservice.config.datasource;

import com.alibaba.druid.pool.DruidDataSource;
import com.ocom.common.entity.master.EntityCompanyPart;

import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 数据库连接池
 */
public class DataSourcePool {

    private Map<String,LinkedList> dataSourceMap;
    /**
     * 初始化连接池的大小
     * @param initialSize
     */
    public DataSourcePool(int initialSize) {
        dataSourceMap=new ConcurrentHashMap<>(10);
    }

    /**
     * 释放连接，放回到连接池
     * @param dataSource
     */
    public void releaseConnection(DruidDataSource dataSource){
        if(dataSource != null){
            if(dataSource!=null && dataSourceMap.containsKey(dataSource.getUrl())){
                synchronized (dataSourceMap) {
                    //连接释放后需要进行通知，这样其他消费者能够感知到连接池中已经归还了一个连接
                    dataSourceMap.get(dataSource.getUrl()).addLast(dataSource);
                    dataSourceMap.notifyAll();
                }
            }
        }
    }

    /**
     * 在mills内无法获取到连接，将会返回null
     * @param mills
     * @return
     * @throws InterruptedException
     */
    public DruidDataSource fetchConnection(EntityCompanyPart entityCompanyPart,long mills) throws InterruptedException{
//        System.out.println("fetchConnection");
//        System.out.println(dataSourceMap);
//        System.out.println(dataSourceMap.get(entityCompanyPart.getDatabaseUrl()));
        if(!dataSourceMap.containsKey(entityCompanyPart.getDatabaseUrl())){
            LinkedList<DruidDataSource> dataSourceList= new LinkedList<>();
        
            //50个连接池
    
            for (int i = 0; i < 150; i++) {
                dataSourceList.addLast(DataSourceDriver.createConnection(entityCompanyPart));
            }
            dataSourceMap.put(entityCompanyPart.getDatabaseUrl(),dataSourceList);
        }


        LinkedList<DruidDataSource> pool =dataSourceMap.get(entityCompanyPart.getDatabaseUrl());

        synchronized (pool) {
            // 无限制等待
            if (mills <= 0) {
                while (pool.isEmpty()) {
                    pool.wait();
                }
                return pool.removeFirst();
            }else{
                long future = System.currentTimeMillis() + mills;
                long remaining = mills;
                while (pool.isEmpty() && remaining > 0) {
                    // 等待超时
                    pool.wait(remaining);
                    remaining = future - System.currentTimeMillis();
                }
                DruidDataSource result = null;
                if (!pool.isEmpty()) {
                    result = pool.removeFirst();
                }
                if(result==null){
                    for (int i = 0; i < 10; i++) {
                        pool.addLast(DataSourceDriver.createConnection(entityCompanyPart));
                    }
                    result = pool.removeFirst();
                    dataSourceMap.put(entityCompanyPart.getDatabaseUrl(),pool);
                    return result;
//                    System.out.println("连接池自动扩容:"+dataSourceList.size());
//                    throw new DataSourceException("无可用数据库链接");
                }
                return result;
            }
        }
    }

}
